{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "view-in-github"
   },
   "source": [
    "<a href=\"https://colab.research.google.com/github/abidlabs/deep-learning-genomics-primer/blob/master/A_Primer_on_Deep_Learning_in_Genomics_Public.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "R46-rwd4hNMn"
   },
   "source": [
    "# Deep Learning in Genomics Primer (*Tutorial*)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "eiiwjw4yhX0P"
   },
   "source": [
    "This tutorial is a supplement to the manuscript, **A Primer on Deep Learning in Genomics** (*Nature Genetics, 2018*) by James Zou, Mikael Huss, Abubakar Abid, Pejman Mohammadi, Ali Torkamani & Amalio Telentil. [Read the accompanying paper here](https://www.nature.com/articles/s41588-018-0295-5).\n",
    "\n",
    "If you have any questions or feedback regarding this tutorial, please contact Abubakar Abid <<a12d@stanford.edu>> or James Zou <<jamesz@stanford.edu>>."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qVh9frJDgVQ-"
   },
   "source": [
    "## Outline "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "_5D80hwMhnaf"
   },
   "source": [
    "* **How to Use This Tutorial**\n",
    "* ** 0. Background ** \n",
    "* **1. Curate the Data**\n",
    "* **2. Select the Architecture and Train**\n",
    "* **3. Evaluate**\n",
    "* **4. Interpret**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "TZcUh5qzgtBY"
   },
   "source": [
    "## How to Use This Tutorial "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "nXiQhNqah2R-"
   },
   "source": [
    "This tutorial utilizes a Colab notebook , which is an interactive computational enviroment that combines live code, visualizations, and explanatory text. To run this notebook, you may first need to make a copy by choosing **File > Save a Copy in Drive** from the menu bar (may take a few moments to save).\n",
    "\n",
    "The notebook is organized into a series of cells. You can modify the Python command and execute each cell as you would a Jupyter notebook. To run all of the cells at once, choose **Runtime > Run all** from the menu bar."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "fb-0kBFAts0-"
   },
   "source": [
    "## 0. Background"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "QABdxctitugX"
   },
   "source": [
    "In this tutorial, we will show how to use deep learning to approach an important problem in functional genomics: **the discovery of transcription-factor binding sites in DNA**.\n",
    "\n",
    "As we go through this notebook, we will  design a neural network that can discover binding motifs in DNA based on the results of an assay that determines whether a longer DNA sequence binds to the protein or not. Here, the longer DNA sequences are our *independent variables* (or *predictors*), while the positive or negative response of the assay is the *dependent variable* (or *response*).\n",
    "\n",
    "We will use simulated data that consists of DNA sequences of length 50 bases (chosen to be artificially short so that the data is easy to play around with), and is labeled with 0 or 1 depending on the result of the assay. Our goal is to build a classifier that can predict whether a particular sequence will bind to the protein and discover the short motif that is the binding site in the sequences that are bound to the protein.\n",
    "\n",
    "(Spoiler alert: the true regulatory motif is *`CGACCGAACTCC`*. Of course, the neural network doesn't know this.)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "aK7wr8n8gzQ_"
   },
   "source": [
    "## 1. Curate the Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "5T-FgQrNq1vS"
   },
   "source": [
    "![alt text](https://github.com/abidlabs/deep-learning-genomics-primer/blob/master/Screenshot%20from%202018-08-01%2020-31-01.png?raw=true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "QRMSFdUSubgX"
   },
   "source": [
    "In order to train the neural network, we must load and preprocess the data, which consists of DNA sequences and their corresponding labels.By processing this data, the network will learn to distinguish sequences that bind to the transcription factor from those that do not. We will split the data into three different sub-datasets:\n",
    "\n",
    "(1) Training dataset: a dataset used to fit the parameters of a model or to define the weights of connections between neurons of a neural network.\n",
    "\n",
    "(2) Validation dataset: a second dataset used to minimize overfitting. The weights of the network are not adjusted with this data set. After each training cycle, if the accuracy over the training data set increases, but the accuracy over the validation data set stays the same or decreases, then there is overfitting on the neural network.\n",
    "\n",
    "(3) Testing dataset: is a third dataset not included in the training nor validation data sets. After all the training and validation cycles are complete, this dataset is used only for testing the final solution in order to measure the actual predictive power of the neural network on new examples.\n",
    "\n",
    "-----------\n",
    "\n",
    "We start by loading the simulated data from an external repository."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 204
    },
    "colab_type": "code",
    "id": "B_F7VoAMhLiX",
    "outputId": "ac75f1bd-27c7-4abc-94ed-b81f81ed453f"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Sequences</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>CCGAGGGCTATGGTTTGGAAGTTAGAACCCTGGGGCTTCTCGCGGA...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>GAGTTTATATGGCGCGAGCCTAGTGGTTTTTGTACTTGTTTGTCGC...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>GATCAGTAGGGAAACAAACAGAGGGCCCAGCCACATCTAGCAGGTA...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>GTCCACGACCGAACTCCCACCTTGACCGCAGAGGTACCACCAGAGC...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>GGCGACCGAACTCCAACTAGAACCTGCATAACTGGCCTGGGAGATA...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           Sequences\n",
       "1  CCGAGGGCTATGGTTTGGAAGTTAGAACCCTGGGGCTTCTCGCGGA...\n",
       "2  GAGTTTATATGGCGCGAGCCTAGTGGTTTTTGTACTTGTTTGTCGC...\n",
       "3  GATCAGTAGGGAAACAAACAGAGGGCCCAGCCACATCTAGCAGGTA...\n",
       "4  GTCCACGACCGAACTCCCACCTTGACCGCAGAGGTACCACCAGAGC...\n",
       "5  GGCGACCGAACTCCAACTAGAACCTGCATAACTGGCCTGGGAGATA..."
      ]
     },
     "execution_count": 7,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import requests\n",
    "\n",
    "#SEQUENCES_URL = 'https://raw.githubusercontent.com/abidlabs/deep-learning-genomics-primer/master/sequences.txt'\n",
    "file_path=\"sequences.txt\" #sequences文件所在路径\n",
    "sequences=pd.read_csv(file_path,header=None) # 读取sequences.txt文件，不把第一列作为列名\n",
    "sequences.rename(columns={0:'Sequences'},inplace=True) #pandas将列名0重命名成Sequences\n",
    "sequences.head() \n",
    "sequences=list(sequences.iloc[:,0]) #将sequences转换成列表的格式\n",
    "\n",
    "#sequences = requests.get(SEQUENCES_URL).text.split('\\n')\n",
    "\n",
    "#sequences = list(filter(None, sequences))  # This removes empty sequences.\n",
    "\n",
    "# Let's print the first few sequences.\n",
    "pd.DataFrame(sequences, index=np.arange(1, len(sequences)+1), \n",
    "             columns=['Sequences']).head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "bzsbNHqWiFek"
   },
   "source": [
    "The next  step is to organize the data into a format that can be passed into a deep learning algorithm. Most deep learning algorithms accept data in the form of vectors or matrices (or more generally, tensors). \n",
    "\n",
    "To get each DNA sequence in the form of a matrix, we use _one-hot encoding_, which encodes every base in a sequence in the form of a 4-dimensional vector, with a separate dimension for each base. We place a \"1\" in the dimension corresponding to the base found in the DNA sequence, and \"0\"s in all other slots. We then concatenate these 4-dimensional vectors together along the bases in the sequence to form a matrix. \n",
    "\n",
    "In the cell below, we one-hot encode the simulated DNA sequences, and show an example of what the one-hot encoded sequence looks like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 170
    },
    "colab_type": "code",
    "id": "IPJD6PuDnaS6",
    "outputId": "9d405c43-efa0-4e80-a19d-272986f5ee8e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Example sequence\n",
      "-----------------------\n",
      "DNA Sequence #1:\n",
      " CCGAGGGCTA ... CGCGGACACC\n",
      "One hot encoding of Sequence #1:\n",
      " [[0. 0. 0. ... 1. 0. 0.]\n",
      " [1. 1. 0. ... 0. 1. 1.]\n",
      " [0. 0. 1. ... 0. 0. 0.]\n",
      " [0. 0. 0. ... 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import LabelEncoder, OneHotEncoder\n",
    "\n",
    "# The LabelEncoder encodes a sequence of bases as a sequence of integers.\n",
    "integer_encoder = LabelEncoder()  \n",
    "# The OneHotEncoder converts an array of integers to a sparse matrix where \n",
    "# each row corresponds to one possible value of each feature.\n",
    "one_hot_encoder = OneHotEncoder(categories='auto')   \n",
    "input_features = []\n",
    "sequence=sequences[0]\n",
    "for sequence in sequences:\n",
    "  integer_encoded = integer_encoder.fit_transform(list(sequence)) #将A,C,G,T转换成0,1,2,3\n",
    "  integer_encoded = np.array(integer_encoded).reshape(-1, 1)\n",
    "  one_hot_encoded = one_hot_encoder.fit_transform(integer_encoded) #将0,1,2,3四个元素转换成四列由0,1组成的数组\n",
    "  input_features.append(one_hot_encoded.toarray())\n",
    "\n",
    "np.set_printoptions(threshold=40)\n",
    "input_features = np.stack(input_features) #将list嵌套的数组转换成numpy数组\n",
    "print(\"Example sequence\\n-----------------------\")\n",
    "print('DNA Sequence #1:\\n',sequences[0][:10],'...',sequences[0][-10:])\n",
    "print('One hot encoding of Sequence #1:\\n',input_features[0].T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "AbBmrEVGrahN"
   },
   "source": [
    "Similarly, we can go ahead and load the labels (_response variables_). In this case, the labels are structured as follows: a \"1\" indicates that a protein bound to the sequence, while a \"0\" indicates that the protein did not. While we could use the labels as a vector, it is often easier to similarly one-hot encode the labels, as we did the features. We carry out that here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 102
    },
    "colab_type": "code",
    "id": "IA9FJeQkr1Ze",
    "outputId": "3a4449a0-96ba-4d55-8658-1b6f025b3fd8"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Labels:\n",
      " [['0' '0' '0' ... '0' '1' '1']]\n",
      "One-hot encoded labels:\n",
      " [[1. 1. 1. ... 1. 0. 0.]\n",
      " [0. 0. 0. ... 0. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "#LABELS_URL = 'https://raw.githubusercontent.com/abidlabs/deep-learning-genomics-primer/master/labels.txt'\n",
    "\n",
    "#labels = requests.get(LABELS_URL).text.split('\\n')\n",
    "#labels = list(filter(None, labels))  # removes empty sequences\n",
    "\n",
    "file_path=\"labels.txt\" #labels文件所在路径\n",
    "labels=pd.read_csv(file_path,header=None) # 读取labels.txt文件，不把第一列作为列名\n",
    "labels.rename(columns={0:'labels'},inplace=True) #pandas将列名0重命名成labels\n",
    "labels.head() \n",
    "labels.shape\n",
    "labels=list(labels.iloc[:,0]) #将labels转换成列表的格式\n",
    "\n",
    "one_hot_encoder = OneHotEncoder(categories='auto')\n",
    "labels = np.array(labels).reshape(-1, 1)\n",
    "input_labels = one_hot_encoder.fit_transform(labels).toarray()\n",
    "\n",
    "print('Labels:\\n',labels.T)\n",
    "print('One-hot encoded labels:\\n',input_labels.T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "MTokFzDZvQR-"
   },
   "source": [
    "We also go ahead and split the data into training and test sets. The purpose of the test set is to ensure that we can observe the performance of the model on new data, not seen previously during training. At a later step, we will further partition the training set into a training and validation set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "P_7LKgvc3Lnn"
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "train_features, test_features, train_labels, test_labels = train_test_split(\n",
    "    input_features, input_labels, test_size=0.25, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "7LQp2ZFrg6dm"
   },
   "source": [
    "## 2. Select the Architecture and Train"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "xBT6Q3j-sjhh"
   },
   "source": [
    "![alt text](https://github.com/abidlabs/deep-learning-genomics-primer/blob/master/Screenshot%20from%202018-08-01%2020-31-49.png?raw=true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "krHJgtK_rzif"
   },
   "source": [
    "Next, we choose a neural network architecture to train the model. In this tutorial, we choose a simple 1D convolutional neural network (CNN), which is commonly used in deep learning for functional genomics applications.\n",
    "\n",
    "A CNN learns to recognize patterns that are generally invariant across space, by trying to match the input sequence to a number of learnable \"filters\" of a fixed size. In our dataset, the filters will be motifs within the DNA sequences. The CNN may then learn to combine these filters to recognize a larger structure (e.g. the presence or absence of a transcription factor binding site). \n",
    "\n",
    "We will use the deep learning library `Keras`. As of 2017, `Keras` has been integrated into `TensorFlow`,  which makes it very easy to construct neural networks. We only need to specify the kinds of layers we would like to include in our network, and the dimensionality of each layer. The CNN we generate in this example consists of the following layers:\n",
    "\n",
    "- _Conv1D_: We define our convolutional layer to have 32 filters of size 12 bases.\n",
    "\n",
    "- _MaxPooling1D_: After the convolution, we use a pooling layer to down-sample the output of the each of the 32 convolutional filters. Though not always required, this is a typical form of non-linear down-sampling used in CNNs.\n",
    "\n",
    "- _Flatten_: This layer flattens the output of the max pooling layer, combining the results of the convolution and pooling layers across all 32 filters. \n",
    "\n",
    "- _Dense_: The first Dense tensor creates a layer (dense_1) that compresses the representation of the flattened layer, resulting in smaller layer with 16 tensors, and the second Dense function converges the tensors into the output layer (dense_2) that consists of the two possible response values (0 or 1).\n",
    "\n",
    "We can see the details of the architecture of the neural network we have created by running `model.summary()`, which prints the dimensionality and number of parameters for each layer in our network. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 377
    },
    "colab_type": "code",
    "id": "dU3imaIns80_",
    "outputId": "851993e7-b2f6-43fd-f061-65e5abd7d76a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv1d (Conv1D)              (None, 39, 32)            1568      \n",
      "_________________________________________________________________\n",
      "max_pooling1d (MaxPooling1D) (None, 9, 32)             0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 288)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 16)                4624      \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 2)                 34        \n",
      "=================================================================\n",
      "Total params: 6,226\n",
      "Trainable params: 6,226\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.keras.layers import Conv1D, Dense, MaxPooling1D, Flatten\n",
    "from tensorflow.keras.models import Sequential\n",
    "\n",
    "model = Sequential()\n",
    "model.add(Conv1D(filters=32, kernel_size=12, \n",
    "                 input_shape=(train_features.shape[1], 4)))\n",
    "model.add(MaxPooling1D(pool_size=4))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(16, activation='relu'))\n",
    "model.add(Dense(2, activation='softmax'))\n",
    "\n",
    "model.compile(loss='binary_crossentropy', optimizer='adam', \n",
    "              metrics=['binary_accuracy'])\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qSOUwoG_vHRA"
   },
   "source": [
    "Now, we are ready to go ahead and train the neural network. We will further divide the training set into a training and validation set. We will train only on the reduced training set, but plot the loss curve on both the training and validation sets. Once the loss for the validation set stops improving or gets worse throughout the learning cycles, it is time to stop training because the model has already converged and may be just overfitting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 447
    },
    "colab_type": "code",
    "id": "LSOmHIM83hXO",
    "outputId": "1bfe5b1d-73ad-4c18-e343-7bcd51b6d3fc"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAe8AAAFnCAYAAACPasF4AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzs3Xl8lOW9///XPUtmJslkmWQmK/tO\nBGRVRJEiCFptrVbAurW25bS1x2rrOadyfhbbCvW06nHpsb/qaW2Px1as5bR1pWpdEWSVHWVNyL4v\nk3W27x8JA9EAAWYyE/J+Ph55JDNz3/d8crG8577u674uIxQKhRAREZF+wxTrAkREROT0KLxFRET6\nGYW3iIhIP6PwFhER6WcU3iIiIv2MwltERKSfUXiLCP/+7//O448/ftJtVq9ezVe/+tVePy8i0aPw\nFhER6WcU3iL9THFxMRdffDFPPfUUCxYsYMGCBXz00UcsXbqUSy65hHvuuSe87auvvspVV13FwoUL\nueWWWygqKgKgrq6O2267jblz57J06VKamprC++zfv5+bbrqJBQsWcPXVV7Njx45e11ZfX8/3vvc9\nFixYwJVXXsmTTz4Zfu0///M/w/XecsstVFRUnPR5ETkxS6wLEJHTV1dXh9vtZs2aNdxxxx3cdddd\n/PnPf8YwDGbPns23v/1tLBYL9957L3/+858ZMmQIv/3tb/nRj37E7373O5566inS09P57W9/S3Fx\nMV/4whcYNWoUwWCQ22+/nW984xtcf/31bN68me985zu89dZbvarr4YcfJjU1lTVr1lBfX8+XvvQl\npkyZQmpqKq+99hovvfQSVquVZ555hnXr1lFQUNDj89dcc02UW1Ckf9OZt0g/5Pf7WbhwIQCjR49m\nwoQJuFwu0tPTcbvdVFZWsnbtWi644AKGDBkCwPXXX8+HH36I3+9n06ZNXHHFFQDk5+czY8YMAA4e\nPEhNTQ1f/vKXAZg6dSoul4utW7f2qq533nmHr3zlKwCkpaUxf/581q5dS0pKCrW1tbz44os0NDRw\n8803c80115zweRE5OYW3SD9kNpux2+0AmEwmEhMTu70WCASoq6sjJSUl/LzT6SQUClFXV0dDQwNO\npzP82tHtGhsbaWtr44orrmDhwoUsXLiQmpoa6uvre1VXbW1tt/dMSUmhpqaGrKwsHn/8cV577TXm\n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\nKt4iIiI2819jXyyOoJzQoQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 576x396 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "history = model.fit(train_features, train_labels, \n",
    "                    epochs=50, verbose=0, validation_split=0.25)\n",
    "\n",
    "plt.figure()\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "P5eKDmX8ODBE"
   },
   "source": [
    "Similarly, we can plot the accuracy of our neural network on the binary classification task. The metric used in this example is the _binary accuracy_, which calculates the proportion of predictions that match labels or response variables. Other metrics may be used in different tasks -- for example, the _mean squared error_ is typically used to measure the accuracy for continuous response variables (e.g. polygenic risk scores, total serum cholesterol level, height, weight and systolic blood pressure)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 376
    },
    "colab_type": "code",
    "id": "J2Jdpa1i8zqM",
    "outputId": "a1bfe431-0bd4-4c51-d283-dbe6fefd13f7"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n7bab+POfl/Fv/3Yjv/3tr33bu/72t0/6jh87dhzDh4/gnntu5/777+Guu+4lLi4uYJ8xYFuvbt68\nmeXLl/Pcc89RVFTEokWLWLlype/x++67j2uuuYbp06fz85//nNtvv53y8nJWrFjBb3/72z6/j7+3\n/tN2gv6jtvQftaX/qCCaWWAAAAidSURBVC39Q+3oP2Gx9erGjRuZNm0aAAUFBdjtdhyOjs3pPR4P\nW7ZsYerUqQAsXryYzMzMQJUiIiJyVghYqNfU1GA2m323LRYL1dXVANTV1ZGQkMDSpUuZN28eTz75\nzVDF/v37ueuuu5g3bx6ffPJJoMoTEREZcM7Y7Peuo/xer5fKykpuuukmsrKyuOOOO1i/fj0jR47k\n3nvv5eqrr6a8vJybbrqJd955h+jonrdCNZvjiYz072z13oY2pH/Ulv6jtvQftaV/qB39x19tGbBQ\nT0tLo6amxne7qqoKq9UKgNlsJjMzk9zcjhmAkyZNYt++fUyZMoVZs2YBkJuby6BBg6isrCQnJ6fH\n97HZnH6tW+eJ/Edt6T9qS/9RW/qH2tF/wuKc+uTJk1m7tmPlnV27dpGWlkZiYiIAkZGR5OTkUFJS\n4ns8Pz+fN954g+XLlwNQXV1NbW0t6enpgSpRRERkQAlYT33ChAmMGjWKwsJCDAYDixcvZtWqVZhM\nJqZPn86iRYt46KGH8Hq9DBs2jKlTp+J0OlmwYAHvvfceLpeLRx99tNehdxEREflGwC5pO1N0SVvo\nUlv6j9rSf9SW/qF29J+wGH4XERGRM0uhLiIiMkAo1EVERAaIsD+nLiIiIh3UUxeR/9/evYVEvfVh\nHP+Khz1apmY6ZVRWZApaIWjYQToRJF0JQVmJF4YhQgRaYlYXonmiLIuKTAgPaJhEN5EFmVFmWKBp\nRSpUWmZq4CFnpAb3RTHvjt79Uure8zo+n7v/GgZ+62GGH2v9YS0RsRNq6iIiInZCTV1ERMROqKmL\niIjYCTV1ERERO6GmLiIiYif+tatXp4KsrCyamppwcHAgLS2NFStW2LqkKeXVq1ckJiYSFxfHnj17\n6O7u5tChQ1gsFnx8fMjLy9NZ/r8oNzeXJ0+e8PXrVxISEggJCVGWv8lkMpGamkp/fz+jo6MkJiYS\nGBioHCfAbDazfft2EhMTiYiIUJbj0NDQwIEDB1i2bBkAAQEBxMfHT1qWWql/9/jxY968eUNlZSWZ\nmZlkZmbauqQpZWRkhIyMDCIiIqxjZ86cISYmhvLychYtWkRVVZUNK5w6Hj16RFtbG5WVlRQVFZGV\nlaUsx+Hu3bsEBwdTWlpKQUEB2dnZynGCzp8/j4eHB6D/90SEh4dTUlJCSUkJR48endQs1dS/q6+v\nZ8uWLQAsXbqUgYEBhoeHbVzV1OHi4sKlS5fw9fW1jjU0NLB582YANm7cSH19va3Km1LCwsI4ffo0\nALNmzcJkMinLcYiKimLfvn0AdHd3YzQaleMEdHR00N7ezoYNGwD9vyfTZGappv5dX18fXl5e1ufZ\ns2fT29trw4qmFicnJwwGww9jJpPJuoXk7e2tPH+Ro6Mjbm5uAFRVVREZGaksJ2Dnzp0kJyeTlpam\nHCcgJyeH1NRU67OyHL/29nb279/Prl27ePDgwaRmqXfqf0On504u5fn77ty5Q1VVFcXFxWzdutU6\nrix/T0VFBS9evCAlJeWH7JTjr7t+/TqrVq1iwYIF//VzZfnr/P39SUpKYtu2bXR2dhIbG4vFYrF+\nPtEs1dS/8/X1pa+vz/r88eNHfHx8bFjR1Ofm5obZbMZgMNDT0/PD1rz8b/fv3+fChQsUFRXh7u6u\nLMehpaUFb29v5s2bR1BQEBaLhRkzZijHcaitraWzs5Pa2lo+fPiAi4uLfpPjZDQaiYqKAmDhwoXM\nmTOHZ8+eTVqW2n7/bu3atdy6dQuA1tZWfH19mTlzpo2rmtrWrFljzbSmpob169fbuKKpYWhoiNzc\nXC5evIinpyegLMejsbGR4uJi4NvrtZGREeU4TgUFBVy7do2rV6+yY8cOEhMTleU43bhxg8uXLwPQ\n29tLf38/0dHRk5albmn7i/z8fBobG3FwcOD48eMEBgbauqQpo6WlhZycHN69e4eTkxNGo5H8/HxS\nU1MZHR3Fz8+PEydO4OzsbOtS/+9VVlZSWFjI4sWLrWPZ2dmkp6cry99gNps5cuQI3d3dmM1mkpKS\nCA4O5vDhw8pxAgoLC5k/fz7r1q1TluMwPDxMcnIyg4ODfPnyhaSkJIKCgiYtSzV1ERERO6HtdxER\nETuhpi4iImIn1NRFRETshJq6iIiInVBTFxERsRNq6iLyj6muriY5OdnWZYhMG2rqIiIidkLHxIoI\nJSUl3Lx5E4vFwpIlS4iPjychIYHIyEhevnwJwKlTpzAajdTW1nLu3DkMBgOurq5kZGRgNBppamoi\nKysLZ2dnPDw8yMnJAf5z2EZHRwd+fn6cPXsWBwcHW05XxG5ppS4yzTU3N3P79m3KysqorKzE3d2d\nhw8f0tnZSXR0NOXl5YSHh1NcXIzJZCI9PZ3CwkJKSkqIjIykoKAAgJSUFDIyMigtLSUsLIx79+4B\n326kysjIoLq6mra2NlpbW205XRG7ppW6yDTX0NDA27dviY2NBWBkZISenh48PT0JDg4GIDQ0lCtX\nrvD69Wu8vb2ZO3cuAOHh4VRUVPDp0ycGBwcJCAgAIC4uDvj2Tj0kJARXV1fg22UWQ0ND//IMRaYP\nNXWRac7FxYVNmzZx7Ngx61hXVxfR0dHW57GxMRwcHH7aNv/r+N+dOO3o6PjTd0Tkn6Htd5FpLjQ0\nlLq6Oj5//gxAWVkZvb29DAwM8Pz5cwCePn3K8uXL8ff3p7+/n/fv3wNQX1/PypUr8fLywtPTk+bm\nZgCKi4spKyuzzYREpjGt1EWmuZCQEHbv3s3evXv5448/8PX1ZfXq1RiNRqqrq8nOzmZsbIyTJ09i\nMBjIzMzk4MGD1ju1MzMzAcjLyyMrKwsnJyfc3d3Jy8ujpqbGxrMTmV50S5uI/KSrq4uYmBjq6ups\nXYqI/AZtv4uIiNgJrdRFRETshFbqIiIidkJNXURExE6oqYuIiNgJNXURERE7oaYuIiJiJ9TURURE\n7MSfthknoFArf7EAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x396 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "plt.plot(history.history['binary_accuracy'])\n",
    "plt.plot(history.history['val_binary_accuracy'])\n",
    "plt.title('model accuracy')\n",
    "plt.ylabel('accuracy')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'validation'])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "6Xy7VhhZg-hN"
   },
   "source": [
    "## 3. Evaluate"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "btf7FyMVsnFA"
   },
   "source": [
    "![alt text](https://github.com/abidlabs/deep-learning-genomics-primer/blob/master/Screenshot%20from%202018-08-01%2020-32-12.png?raw=true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "eQ_xYCvfvFlE"
   },
   "source": [
    "The best way to evaluate whether the network has learned to classify sequences is to evaluate its performance on a fresh test set consisting of data that it has not observed at all during training. Here, we evaluate the model on the test set and plot the results as a confusion matrix. Nearly every test sequence should be correctly classified."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 478
    },
    "colab_type": "code",
    "id": "J1bvxV9J-EMT",
    "outputId": "43bd6cbf-671f-4701-b8b2-569a3871d394"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Confusion matrix:\n",
      " [[251   8]\n",
      " [  2 239]]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/matplotlib/cbook/__init__.py:424: MatplotlibDeprecationWarning: \n",
      "Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead.\n",
      "  warn_deprecated(\"2.2\", \"Passing one of 'on', 'true', 'off', 'false' as a \"\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nBxERyfL/AFWRYSKBkisCAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 576x396 with 2 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "import itertools\n",
    "\n",
    "predicted_labels = model.predict(np.stack(test_features))\n",
    "cm = confusion_matrix(np.argmax(test_labels, axis=1), \n",
    "                      np.argmax(predicted_labels, axis=1))\n",
    "print('Confusion matrix:\\n',cm)\n",
    "\n",
    "cm = cm.astype('float') / cm.sum(axis = 1)[:, np.newaxis]\n",
    "\n",
    "plt.imshow(cm, cmap=plt.cm.Blues)\n",
    "plt.title('Normalized confusion matrix')\n",
    "plt.colorbar()\n",
    "plt.xlabel('True label')\n",
    "plt.ylabel('Predicted label')\n",
    "plt.xticks([0, 1]); plt.yticks([0, 1])\n",
    "plt.grid('off')\n",
    "for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
    "    plt.text(j, i, format(cm[i, j], '.2f'),\n",
    "             horizontalalignment='center',\n",
    "             color='white' if cm[i, j] > 0.5 else 'black')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UBdJQC1Ug__3"
   },
   "source": [
    "## 4. Interpret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "6qmKi1ResqHo"
   },
   "source": [
    "![alt text](https://github.com/abidlabs/deep-learning-genomics-primer/blob/master/Screenshot%20from%202018-08-01%2020-32-31.png?raw=true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UpAwoK9SwAbb"
   },
   "source": [
    "Your results so far should allow you to conclude that the neural network is quite effective in learning to distinguish sequences that bind the protein from sequences that do not. But can we understand _why_ the neural network classifies a training point in the way that it does? To do so, we can compute a simple _saliency map_, which is the gradient of the model's prediction with respect to each individual nucleotide. \n",
    "\n",
    "In other words, the saliency maps shows how the output response value changes with respect to a small changes in input nucleotide sequence. All the positive values in the gradients tell us that a small change to that nucleotide will change the output value. Hence, visualizing these gradients for a given input sequence, should provide some clues about what nucleotides form the binding motive that we are trying to identify."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "WNT_Au-dAP8a"
   },
   "outputs": [],
   "source": [
    "import tensorflow.keras.backend as K\n",
    "\n",
    "def compute_salient_bases(model, x):\n",
    "  input_tensors = [model.input]\n",
    "  gradients = model.optimizer.get_gradients(model.output[0][1], model.input)\n",
    "  compute_gradients = K.function(inputs = input_tensors, outputs = gradients)\n",
    "  \n",
    "  x_value = np.expand_dims(x, axis=0)\n",
    "  gradients = compute_gradients([x_value])[0][0]\n",
    "  sal = np.clip(np.sum(np.multiply(gradients,x), axis=1),a_min=0, a_max=None)\n",
    "  return sal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 349
    },
    "colab_type": "code",
    "id": "uObq5iC4BG1g",
    "outputId": "147a7cdf-375f-4832-8b4e-e3450dcf2115"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nuXDhgunZs6dp3bq1MebyftmiRQuTkJBgjDF5jouz/fTEiROmTp06jsdt2LDBtGnTJkdOV8733Xff\nbX766SdjjDETJ040L730kjHGmKFDhzr20YMHD5o6deqYVatWZYtfu3at6d69u7l48aJJTk42LVu2\nNAcPHjQbN240HTt2NBcvXjQXLlwwERERZu3atcaY7M9Ree3vXbp0MXv37jXGGPP777+b4cOH5+jL\nlftC69atzYgRI7LN8enTp/Ocy6zi4+NNvXr1HMfw6NGjzZgxY/Lsq7Nj5sq/8xqTnj17Ov6dVc+e\nPU3Xrl1NamqqSU1NNW3btjVffvmlSU9PN40aNXIc/3PnznXk4Ox5taBjnbWfeb1WZpXf174FCxaY\nfv36mfT0dHP+/HnTtWtXx3i0bt3a8TqYdd+5cswWLFhgXnjhhRw5AKWFx62UHj16VGFhYU4/tc3L\ntm3bFBUV5fjv3nvvVWxsrBuyBPLPZrPp3XffVZs2bbR06VKFhYWpQ4cO+uKLLyRJ9erV07Zt21Sx\nYkV5eXmpQYMGOnHihNP2tmzZovbt2yskJESS9MQTTzjakqSWLVuqcuXK8vHx0e23364zZ87o999/\nV1JSklq2bClJ6tmzp+bOnau6devK399fu3fvlnT5k/j27dvnut0GDRooKChIAQEBCg4O1oMPPihJ\nuv322x0rdX379tW8efNks9lUqVIl3XbbbTp58qSjjUcffVTe3t4KCgpSw4YNc13hzGrbtm169NFH\nVaFCBXl7e6tLly7atWtXtr56eeX+NFarVi01aNBAkhQREaEffvhBkjR27FjHqYg33HCDgoODdfLk\nSZUtW1Y2m00rV65UfHy8IiIi1K9fPx07dkwJCQmKjIyUJDVs2FCBgYH6/vvvHf/fuXOnYxWhdu3a\nefbJz89PYWFhkqS6des6TuvKateuXbr//vtVq1YtSdJjjz2mvXv36tKlS5KkRo0aqUaNGrLZbKpd\nu7bOnDmj1NRU7d2717ESUKtWLTVs2DDHaml6erq++eYbx4pnjRo1dP/992vPnj155p2bhx9+WJJU\np04dpaWlKSkpyeX+mdWtt96qe+65R5IUHh6u77//XtLlFdjM/CpXrqw2bdpo165duu6665SYmKhP\nPvlE586dU1RUlB599NF85RoeHq4tW7ZIkg4fPiwfHx/VrVtXW7duVdeuXeXv7y8fHx899thjueYb\nFBSknTt3av/+/fL19dXMmTNVtWpVp/FpaWk6fPiw43hq3769ypYt6zLPrVu3qkePHvL19VWFChX0\nyCOPZMunU6dO8vb2VkhIiIKCgnTmzBnt2rVLDRo0UEhIiGw2m2bMmKE+ffro66+/VuPGjXX77bdL\nurwqt2XLFmVkZCgoKEibNm3S4cOHFRAQoHnz5snX1zdbLidPnlRycrLuuOMOSdK3336rxo0bq2rV\nqipbtqy6du2a7fF33323AgMDHf3IbVxc7aeXLl1Sly5dJDk/Pq506623ql69epIu74tnzpyRJO3f\nv98x/vXr19ctt9ySI/brr79WeHi4ypQpo4oVK2rDhg266667FB4erlWrVqlMmTIqW7as7rrrrlyf\nl/Pa34OCgrR27Vr973//00033aQZM2a47IuUc45jYmLynMusgoKC9N1336latWqSLj9XZObtrK/5\nld8xyS2ufPnyKl++vFq2bKkffvhBPj4++uabbxzHf9Y8nT2vFvZY5/ZamZv8vPZt27ZNjz/+uHx8\nfFSuXDl16tQp22tVftx9992O1ymgNPKxOoGsUlNTNWnSJDVt2vSa4lu1aqVWrVpJkv744w9Nnz7d\n8eQFWMnf319Dhw7V0KFDFR8fr9WrV2v48OFat26dqlevrqlTp2rv3r2SLp9Cm7kf5yY5OVlffvml\ndu7cKenyKVlZT6Hy9/d3/Nvb21sZGRlKSkrKdruPj498fC4f/h07dtSnn36q++67T/v27dOUKVNy\n3a6fn1+2ditUqCBJ8vLykt1ulyQdP35c06ZN07Fjx+Tl5aWYmBjHG0xJqlSpUrZ/53aaclaJiYk5\nYhISEnJt70qZb44lqWLFijp37pwk6aefftKMGTN05swZeXl5KS4uTna7XWXKlNGSJUs0f/58zZ07\nV3fccYcmTJiglJQUXbhwQREREY72/vnnH509e1YRERE6d+6cZs+erWPHjunhhx/Wiy++mOPNfVZZ\n5yHr2GWVlJSk6667LluMMUZJSUk52sic4+TkZBlj1L17d8d9qampatKkSba2z549K2NMtjYyi72r\nlXlKp7e3t6TLp/e52j+zyjp/1113nWN/SExMzNb/6667Tn/99ZdCQkI0d+5cLV68WJMmTdJ9992X\n7+8eh4WFadq0aUpLS9PmzZsd85mcnKx33nlHH330kaTLp31n3Xcy9enTx/EG+a+//tKTTz6pIUOG\nOI0/e/aspP+bK5vNpoCAAJd5Jicna+rUqZo5c6aky6fz1q9f33F/5phL2Y/vrOOVWfwmJydr//79\nateuXbb4s2fP6oUXXtCCBQs0bNgwpaWlacCAAXryySez5ZKYmKjKlSs7Pvj5+++/s83Zla+vWe9z\nNi6u9lNnzy15ye14kC4/l2Ydr6xjlOnKscvcdmJioiZNmqSff/5ZNptN8fHx6t27d474vPb3KVOm\n6K233tJTTz2lcuXKafjw4dnmwpkrn2szj29ncxkUFOS4LSMjQ3PmzHEUrCkpKbr55pvz7Gt+5XdM\nrpT1ePL391dcXJwkadmyZVqzZo0uXryoixcvymazSZLT59XCHmtn+82V8vPa5+q1Kj+CgoKuOgYo\nSTyqKPX19dXChQu1cOFCx22//faboqOjZbPZ5Ofnp2nTpuX6wnKluXPn6rnnnnNnukC+xMTE6OTJ\nk2rUqJEkqUqVKurfv782btyoX3/9VV9++aWOHz+u1atXy8/PT7Nmzcpzhb9q1arq3LnzVV0NMyAg\nQGfPnpXdbpeXl5fS09MVGxurmjVrqkOHDnr88cf14IMP6t57783X8eVMdHS06tatqzfffFPe3t7Z\n3nhKchRV0uXiKK+iUro8Vplv7jNj8nvBoMwiVLr8Zrpy5cqSpJEjR6p379564oknZLPZsl3Qp06d\nOpozZ44uXryoRYsWacKECXrttdfk5+enjRs35rqd7t27q3v37oqNjdWQIUO0du1aPf744/nK0Zmg\noCDHqmFmX7y8vPIsaoKCguTt7a1Vq1ZlexN1pYCAAHl5eencuXOO8b/yjW1BXM3+mXVus+aTOe/V\nq1d3PC5z3ps0aaImTZooNTVV06dP12uvvaZ//etfLrdVuXJl1a9fX7t379bmzZv16quvOvINDQ1V\nz54984z38fFR//791b9/f/3+++/q16+fGjZs6DQ+8/tp//zzj/z9/WW32x39vfINcNYPZ6pWraq+\nffuqdevWLvuUKSAgINv+8s8//+jChQuqWrWqmjVrpjlz5uQaN3z4cA0fPlw//vij+vXrp2bNmjkK\nGEk5LrpSsWJFx3e6JTlWiXLjbFwuXbrkdD/NelZFYbjuuuv0zz//OP7O7YOXgICAbM9L8fHxKleu\nnGbNmiUfHx998skn8vX11YgRI3LdRl77e5UqVTRu3DiNGzdOO3fu1JAhQ/TAAw/keXw642ouM23Y\n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\n",
      "text/plain": [
       "<Figure size 1152x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sequence_index = 1999  # You can change this to compute the gradient for a different example. But if so, change the coloring below as well.\n",
    "sal = compute_salient_bases(model, input_features[sequence_index])\n",
    "\n",
    "plt.figure(figsize=[16,5])\n",
    "barlist = plt.bar(np.arange(len(sal)), sal)\n",
    "[barlist[i].set_color('C1') for i in range(5,17)]  # Change the coloring here if you change the sequence index.\n",
    "plt.xlabel('Bases')\n",
    "plt.ylabel('Magnitude of saliency values')\n",
    "plt.xticks(np.arange(len(sal)), list(sequences[sequence_index]));\n",
    "plt.title('Saliency map for bases in one of the positive sequences'\n",
    "          ' (green indicates the actual bases in motif)');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "voPIrz9TPtIH"
   },
   "source": [
    "The results above should show high saliency values for the bases _CGACCGAACTCC_ appearing in the DNA sequence. If you recall from the top of the document, this is exactly the motif that we embedded in the positive sequences! The raw saliency values may be non-zero for other bases as well -- the gradient-based saliency map method is not perfect, and there other more complex interpretation methods that are used in practice to obtain better results.  \n",
    "\n",
    "Furthermore, we may explore other architectures for our neural network to see if we can improve performance on the validation dataset. For example, we could choose different _hyper-parameters_, which are variables that define the network structure (e.g. the number of dense or convolutional layers, the dimensionality of each layer, etc.) and variables that determine how the network is trained (e.g. the number of epochs, the learning rate, etc.). Testing different hyper-parameter values or performing a hyper-parameter search grid are good practices that may help the deep learning procedure to obtain a clearer signal for classifying sequences and identifying the binding motif."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "1lGpn-5IZ3VN"
   },
   "source": [
    "## Acknowledgements "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "BVFi5aDBZ7M8"
   },
   "source": [
    "Thanks to Julia di lulio and Raquel Dias for helpful comments and suggestions in preparing this notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "vY3uDUtcLwXe"
   },
   "source": [
    "# GitHub Repository"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "U8soCi3qLzmc"
   },
   "source": [
    "If you found this tutorial helpful, kindly star the [associated GitHub repo](https://github.com/abidlabs/deep-learning-genomics-primer/blob/master/A_Primer_on_Deep_Learning_in_Genomics_Public.ipynb) so that it is more visible to others as well!"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "include_colab_link": true,
   "name": "A Primer on Deep Learning in Genomics - Public.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python [conda env:.conda-dl_keras]",
   "language": "python",
   "name": "conda-env-.conda-dl_keras-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
